/**
 * 
 * 
 */
#include <iostream>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/variables_map.hpp>
#include <boost/program_options/parsers.hpp>

#include "kb/kbase.hpp"
#include "utils/logger.hpp"
#include "input/interpreter.hpp"
#include "inference/bchaining.hpp"

using namespace std;
using namespace mashine::kb;
using namespace mashine::input;
namespace po = boost::program_options;

int main(int argc, char **argv)
{
	// Declare the supported options.
	po::options_description desc("Allowed options");
	desc.add_options()
		("help", "produce help message")
		("kb-file", po::value<std::string>(), "path to knowlege base file")
		("no-console-log", "disablev logging")
		("log-file", po::value<std::string>(), "disablev logging")
	;

	po::variables_map vm;
	po::store(po::parse_command_line(argc, argv, desc), vm);
	po::notify(vm);    
	
	cout << "\n"; 

	if (vm.count("help")) {
		cout << desc << "\n";
		
		return 0;
	}
		
	cout << " ::: logging started ...\n";
	initLogger(
			(vm.count("log-file")) ? vm["kb-file"].as<std::string>() : "test.log", 
			!vm.count("no-console-log")
			);

	if (vm.count("kb-file")) {
		cout << " ::: knowlege base from file " << vm["kb-file"].as<std::string>() << " ...\n";
		
		
	}
		
	Interpreter::instance()->setBase(new KnowledgeBase());
	Interpreter::instance()->getBase()->setInferenceStrategy(
			new mashine::inference::BackwardChainingStrategy(Interpreter::instance()->getBase()));
		
	cout << " ::: interpreter started ...\n\n" << " : ";
	
	string buffer;
    while (getline(cin, buffer))
    {
        if (buffer[0] == '<') { break; }
		
		APP_LOGGER(info) << "String from terminal : " << buffer;
		
		Interpreter::instance()->interprete(buffer);
				
		APP_LOGGER(info) << "Interpreter out : " << 
				Interpreter::instance()->getLastMessage();
		cout << std::endl << " : ";
    }

	delete Interpreter::instance()->getBase();
	delete Interpreter::instance();
	
    APP_LOGGER(info) << "Finish Programm. Exit Code : " << 0;

    return 0;
}
